package com.ssy.lingxi.platform.manage.serviceimpl.content;

import com.querydsl.jpa.impl.JPAQuery;
import com.querydsl.jpa.impl.JPAQueryFactory;
import com.ssy.lingxi.common.constant.basic.EnableDisableStatus;
import com.ssy.lingxi.common.exception.BusinessException;
import com.ssy.lingxi.common.model.dto.UserLoginCacheDTO;
import com.ssy.lingxi.common.response.PageData;
import com.ssy.lingxi.common.response.ResponseCode;
import com.ssy.lingxi.common.response.Wrapper;
import com.ssy.lingxi.platform.manage.constant.ColumnTypeEnum;
import com.ssy.lingxi.platform.manage.constant.CommonBooleanEnum;
import com.ssy.lingxi.platform.manage.entity.content.ContentColumn;
import com.ssy.lingxi.platform.manage.entity.content.QContentColumn;
import com.ssy.lingxi.platform.manage.entity.content.QContentInformation;
import com.ssy.lingxi.platform.manage.model.request.common.CommonIdRequest;
import com.ssy.lingxi.platform.manage.model.request.common.CommonStatusRequest;
import com.ssy.lingxi.platform.manage.model.request.content.ContentColumnPageRequest;
import com.ssy.lingxi.platform.manage.model.request.content.ContentColumnRequest;
import com.ssy.lingxi.platform.manage.model.response.HotColumnResponse;
import com.ssy.lingxi.platform.manage.repository.ContentColumnRepository;
import com.ssy.lingxi.platform.manage.repository.ContentInformationRepository;
import com.ssy.lingxi.platform.manage.service.content.IContentColumnService;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Sort;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 栏目管理 - 业务实现层
 *
 * @author fhj
 * @version 2.0.0
 * @date 2020/9/18
 */
@Service
public class ContentColumnServiceImpl implements IContentColumnService {

    @Resource
    private ContentColumnRepository contentColumnRepository;
    @Resource
    private ContentInformationRepository contentInformationRepository;
    @Resource
    private JPAQueryFactory jpaQueryFactory;

    /**
     * 列表
     * @param request 请求实体
     * @return 操作结果
     */
    @Override
    public Wrapper<PageData<ContentColumn>> page(ContentColumnPageRequest request) {
        QContentColumn qContentColumn = QContentColumn.contentColumn;
        JPAQuery<ContentColumn> jpaQuery = jpaQueryFactory.select(qContentColumn).from(qContentColumn);

        if (StringUtils.isNotBlank(request.getName())) {
            jpaQuery.where(qContentColumn.name.contains(request.getName()));
        }

        long totalCount = jpaQuery.fetchCount();
        List<ContentColumn> columnList = jpaQuery.orderBy(qContentColumn.createTime.desc()).limit(request.getPageSize()).offset((long) (request.getCurrent() - 1) * request.getPageSize()).fetch();
        return Wrapper.success(new PageData<>(totalCount, columnList));
    }

    /**
     * 详情
     * @param request 请求实体
     * @return 操作结果
     */
    @Override
    public Wrapper<ContentColumn> get(CommonIdRequest request) {
        ContentColumn contentColumn = contentColumnRepository.findById(request.getId()).orElse(null);
        if (contentColumn == null) {
            throw new BusinessException(ResponseCode.MAN_RECORDS_DON_T_EXIST);
        }
        return Wrapper.success(contentColumn);
    }

    /**
     * 新增
     * @param request 请求实体
     * @param user 当前登录用户
     * @return 操作结果
     */
    @Override
    @Transactional
    public Wrapper<Void> add(ContentColumnRequest request, UserLoginCacheDTO user) {
        if (contentColumnRepository.existsBySortAndType(request.getSort(), request.getType())) {
            return Wrapper.fail(ResponseCode.PLATFORM_MANAGE_SORT_CANNOT_BE_REPEATED);
        }

        ContentColumn contentColumn = new ContentColumn();
        BeanUtils.copyProperties(request, contentColumn);
        contentColumnRepository.saveAndFlush(contentColumn);
        return Wrapper.success();
    }

    /**
     * 修改
     * @param request 请求实体
     * @param user 当前登录用户
     * @return 操作结果
     */
    @Override
    @Transactional
    public Wrapper<Void> update(ContentColumnRequest request, UserLoginCacheDTO user) {
        ContentColumn existsContentColumn = contentColumnRepository.findBySortAndType(request.getSort(), request.getType());
        if (existsContentColumn != null && existsContentColumn.getId() - request.getId() != 0) {
            return Wrapper.fail(ResponseCode.PLATFORM_MANAGE_SORT_CANNOT_BE_REPEATED);
        }

        ContentColumn contentColumn = contentColumnRepository.findById(request.getId()).orElse(null);
        if (contentColumn == null) {
            throw new BusinessException(ResponseCode.MAN_RECORDS_DON_T_EXIST);
        }
        if (contentColumn.getStatus().equals(CommonBooleanEnum.YES.getCode())) {
            throw new BusinessException(ResponseCode.MAN_DATA_STATUS_INCORRECT_OPERATE_INVALID);
        }

        BeanUtils.copyProperties(request, contentColumn);
        contentColumnRepository.saveAndFlush(contentColumn);
        return Wrapper.success();
    }

    /**
     * 停用/启用
     * @param request 请求实体
     * @param user 当前登录用户
     * @return 操作结果
     */
    @Override
    @Transactional
    public Wrapper<Void> updateStatus(CommonStatusRequest request, UserLoginCacheDTO user) {
        //停用栏目时, 需要先判断该栏目是否被资讯信息所关联, 如果有则不能被停用
        if (request.getEnableStatus().equals(CommonBooleanEnum.NO.getCode())) {
            if (contentInformationRepository.existsAllByColumnId(request.getId())) {
                throw new BusinessException(ResponseCode.MAN_DATA_RELATION_INFORMATION);
            }
        }

        ContentColumn contentColumn = contentColumnRepository.findById(request.getId()).orElse(null);
        if (contentColumn == null) {
            throw new BusinessException(ResponseCode.MAN_RECORDS_DON_T_EXIST);
        }
        contentColumn.setStatus(request.getEnableStatus());
        contentColumnRepository.saveAndFlush(contentColumn);
        return Wrapper.success();
    }

    /**
     * 删除
     * @param request 请求实体
     * @param user 当前登录用户
     * @return 操作结果
     */
    @Override
    @Transactional
    public Wrapper<Void> delete(CommonIdRequest request, UserLoginCacheDTO user) {
        //删除栏目时, 需要先判断该栏目是否被资讯信息所关联, 如果有则不能被停用
        if (contentInformationRepository.existsAllByColumnId(request.getId())) {
            throw new BusinessException(ResponseCode.MAN_DATA_RELATION_INFORMATION);
        }

        ContentColumn contentColumn = contentColumnRepository.findById(request.getId()).orElse(null);
        if (contentColumn == null) {
            throw new BusinessException(ResponseCode.MAN_RECORDS_DON_T_EXIST);
        }
        if (contentColumn.getStatus().equals(EnableDisableStatus.ENABLE.getCode())) {
            throw new BusinessException(ResponseCode.MAN_DATA_STATUS_INCORRECT_OPERATE_INVALID);
        }
        contentColumnRepository.delete(contentColumn);
        return Wrapper.success();
    }

    /**
     * 所有
     * @param type 栏目类型
     * @return 操作结果
     */
    @Override
    public Wrapper<List<ContentColumn>> all(Integer type) {
        List<ContentColumn> all;
        if (type != null) {
            all = contentColumnRepository.findAllByStatusAndType(CommonBooleanEnum.YES.getCode(), type, Sort.by("id"));
        } else {
            all = contentColumnRepository.findAllByStatus(CommonBooleanEnum.YES.getCode(), Sort.by("id"));
        }
        return Wrapper.success(all);
    }

    /**
     * 所有（市场行情）
     * @return 操作结果
     */
    @Override
    public Wrapper<List<ContentColumn>> allByMarket() {
        List<ContentColumn> all = contentColumnRepository.findAllByStatusAndType(CommonBooleanEnum.YES.getCode(), ColumnTypeEnum.MARKET.getCode(), Sort.by("sort"));
        return Wrapper.success(all);
    }

    /**
     * 热门栏目
     * @return 操作结果
     */
    @Override
    public Wrapper<List<HotColumnResponse>> hot() {
        QContentInformation qContentInformation = QContentInformation.contentInformation;
        QContentColumn qContentColumn = QContentColumn.contentColumn;
        List<ContentColumn> columnList = jpaQueryFactory.select(qContentColumn)
                .from(qContentColumn)
                .where(qContentColumn.status.eq(1))
                .orderBy(qContentColumn.sort.desc()).fetch();
        List<HotColumnResponse> list = columnList.stream().map(p -> {
            HotColumnResponse response = new HotColumnResponse();
            response.setId(p.getId());
            response.setName(p.getName());
            response.setNum(Math.toIntExact(jpaQueryFactory.select(qContentInformation.id.count()).from(qContentInformation).where(qContentInformation.status.eq(2), qContentInformation.columnId.eq(p.getId())).fetchFirst()));
            return response;
        }).collect(Collectors.toList());
        return Wrapper.success(list.stream().filter(a -> !a.getNum().equals(0)).collect(Collectors.toList()));
    }
}
